package top.v5it.logback.push.channel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import top.v5it.logback.push.Message;
import top.v5it.logback.push.client.AbstractParser;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Optional;

/**
 * 推送策略
 *
 * @author zhanpu
 * @date 2022/9/7
 */
public interface ChannelPushStrategy {

    /**
     * 推送接口
     *
     * @param pushConfig
     * @param payload
     * @param failedCallback
     * @param <E>
     * @return
     */
    <E> boolean push(Map<String, Object> pushConfig, byte[] payload, VoidFunc failedCallback);

    /**
     * 获取日志信息
     *
     * @param payload
     * @return
     */
    default LogInfo getLogInfo(byte[] payload) {
        return Optional.of(payload)
                .map(String::new)
                .filter(StrUtil::isNotEmpty)
                .filter(JSONUtil::isTypeJSON)
                .map(JSONUtil::parseObj)
                .map(t -> t.toBean(LogInfo.class))
                .map(t -> (StrUtil.equals(t.getLogger(), AbstractParser.class.getName()) || StrUtil.isNotBlank(t.getMessage().getSourceName())) ? t.setLogger(t.getMessage().getSourceName()) : t)
                .orElseGet(() ->
                        new LogInfo()
                                .setLevel("未知级别")
                                .setMessage(new Message().setTitle("未知标题").setDescription(new String(payload)))
                                .setTimestamp(LocalDateTime.now(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(DatePattern.ISO8601_PATTERN)))
                );
    }

    /**
     * 给级别添加颜色
     *
     * @param pushConfig
     * @param level
     * @return
     */
    default String getLevel(Map<String, Object> pushConfig, String level) {
        final String errorColor = MapUtil.getStr(pushConfig, "error.level.color");
        final String warnColor = MapUtil.getStr(pushConfig, "warn.level.color");
        String color = MapUtil.getStr(pushConfig, "all.level.color");
        if (StrUtil.equalsIgnoreCase("ERROR", level)) color = errorColor;
        else if (StrUtil.equalsIgnoreCase("WARN", level)) color = warnColor;
        return Optional.ofNullable(color)
                .filter(StrUtil::isNotBlank)
                .map(t -> "<font color='" + t + "'>" + level + "</font>")
                .orElse(level);
    }
}
